package logger

import (
	"flag"
	"os"

	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var (
	ownLogger        *zap.Logger
	ownSugaredLogger *zap.SugaredLogger
	logLevel         = flag.String("log.level", "info", "debug or info")
)

var (
	// 设置一些基本日志格式, 参考zap的NewProductionEncoderConfig做微调
	/*  # NewProductionEncoderConfig
	    TimeKey:        "ts",
	    LevelKey:       "level",
	    NameKey:        "logger",
	    CallerKey:      "caller",
	    FunctionKey:    zapcore.OmitKey,
	    MessageKey:     "msg",
	    StacktraceKey:  "stacktrace",
	    LineEnding:     zapcore.DefaultLineEnding,
	    EncodeLevel:    zapcore.LowercaseLevelEncoder,
	    EncodeTime:     zapcore.EpochTimeEncoder,
	    EncodeDuration: zapcore.SecondsDurationEncoder,
	    EncodeCaller:   zapcore.ShortCallerEncoder,
	*/
	encoder = zapcore.NewJSONEncoder(
		zapcore.EncoderConfig{
			TimeKey:        "ts",
			LevelKey:       "level",
			NameKey:        "logger",
			CallerKey:      "caller",
			FunctionKey:    zapcore.OmitKey,
			MessageKey:     "msg",
			StacktraceKey:  "stacktrace",
			LineEnding:     zapcore.DefaultLineEnding,
			EncodeLevel:    zapcore.LowercaseLevelEncoder,
			EncodeTime:     zapcore.ISO8601TimeEncoder,
			EncodeDuration: zapcore.SecondsDurationEncoder,
			EncodeCaller:   zapcore.ShortCallerEncoder,
		})
)

func Init() {

	// 实现判断日志等级的interface

	infoLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl >= zapcore.InfoLevel
	})
	errorLevel := zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
		return lvl >= zapcore.ErrorLevel
	})
	if *logLevel == "debug" {
		infoLevel = zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
			return lvl >= zapcore.DebugLevel
		})
	}

	// 最后创建具体的Logger

	core := zapcore.NewTee(
		zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), infoLevel),
		zapcore.NewCore(encoder, zapcore.AddSync(os.Stderr), errorLevel),
	)

	//core := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(os.Stdout, infoWriter, errorWriter), zapcore.DebugLevel)
	ownLogger = zap.New(core, zap.AddCaller(), zap.AddCallerSkip(1)) // 需要传入 zap.AddCaller() 才会显示打日志点的文件名和行数
	ownSugaredLogger = ownLogger.Sugar()
}

type Logger interface {
	Log(keyvals ...interface{}) error
}

func Debug(args ...interface{}) {
	ownSugaredLogger.Debug(args...)
}

func Debugf(template string, args ...interface{}) {
	ownSugaredLogger.Debugf(template, args...)
}

func Info(args ...interface{}) {
	ownSugaredLogger.Info(args...)
}

func Infof(template string, args ...interface{}) {
	ownSugaredLogger.Infof(template, args...)
}

func Infow(msg string, keysAndValues ...interface{}) {
	ownSugaredLogger.Infow(msg, keysAndValues...)
}

func Warn(args ...interface{}) {
	ownSugaredLogger.Warn(args...)
}

func Warnf(template string, args ...interface{}) {
	ownSugaredLogger.Warnf(template, args...)
}

func Error(args ...interface{}) {
	ownSugaredLogger.Error(args...)
}

func Errorf(template string, args ...interface{}) {
	ownSugaredLogger.Errorf(template, args...)
}

func DPanic(args ...interface{}) {
	ownSugaredLogger.DPanic(args...)
}

func DPanicf(template string, args ...interface{}) {
	ownSugaredLogger.DPanicf(template, args...)
}

func Panic(args ...interface{}) {
	ownSugaredLogger.Panic(args...)
}

func Panicf(template string, args ...interface{}) {
	ownSugaredLogger.Panicf(template, args...)
}

func Fatal(args ...interface{}) {
	ownSugaredLogger.Fatal(args...)
}

func Fatalf(template string, args ...interface{}) {
	ownSugaredLogger.Fatalf(template, args...)
}
